﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.Infrastructure;
using System.Reflection;
using System.Data.Entity.ModelConfiguration;
using Cat.Domain.Entities;

namespace Cat.Domain.Shared
{
    public class SqlServerContext : DbContext, IDbContext
    {
        public SqlServerContext()
            : this("catConnection")
        {
        }

        public SqlServerContext(string connectionString)
            : base(connectionString)
        {

        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            if (modelBuilder == null)
            {
                return;
            }

            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

            // 移除对MetaData表的查询验证
            modelBuilder.Conventions.Remove<IncludeMetadataConvention>();

            // 获取一个基本类型
            var mapType = typeof(SqlServerContext);

            // 利用反射查找所有的继承自EntityTypeConfiguration的类型
            var typeList = Assembly.GetAssembly(mapType).GetTypes();
            var configuageTypeList = from configuageType in typeList
                                     where configuageType.BaseType != null
                                     && configuageType.BaseType.IsGenericType
                                     && configuageType.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)
                                     select configuageType;

            // 循环添加
            foreach (var type in configuageTypeList)
            {
                // 创建类型的实例
                dynamic instanceItem = Activator.CreateInstance(type);

                // 往模型添加类型
                modelBuilder.Configurations.Add(instanceItem);
            }

            base.OnModelCreating(modelBuilder);
        }

        public new IDbSet<T> Set<T>() where T : BaseEntity
        {
            return ((DbContext)this).Set<T>();
        }
    }
}
